package com.sniff.atp.service.wms.storage;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.sniff.atp.dto.ContentDTO;
import com.sniff.atp.dto.WMSLoginDTO;
import com.sniff.atp.enums.api.WmsAPI;
import com.sniff.atp.enums.status.WmsRegionStatus;
import com.sniff.atp.service.order.PurchaseAllotOrder;
import com.sniff.atp.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @BelongsProject: sniff-atp
 * @BelongsPackage: com.sniff.atp.service.wms
 * @Author: zxy
 * @CreateTime: 2022-11-04 11:55
 * @Description: wms入库流程
 * @Version: 1.0
 */
@Service
public class WMSStorageService {

    @Autowired
    private PurchaseAllotOrder purchaseAllotOrder;

    /**
     * WMS: 选择登录仓库
     */
    public String switchHouse(WMSLoginDTO wmsLoginDTO, String wareCode){
        HashMap<String, Object> param = new HashMap<>();
        param.put("wareCode", wareCode);

        String result = new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPost(WmsAPI.WMS_API1.getApi(), param);
        return result;
    }

    /**
     *  WMS: 入库签收
     * @param wmsLoginDTO
     * @param expressNo
     * @return
     */
    public String queryByExpressNo(WMSLoginDTO wmsLoginDTO, String expressNo){
        HashMap<String, String> param = new HashMap<>();
        param.put("expressNo", expressNo);

        String result = new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doGet(WmsAPI.WMS_API2.getApi(), param);
        return result;
    }

    /**
     * WMS: 批量签收
     */
    public String saveSignRecords(WMSLoginDTO wmsLoginDTO, String purchaseNo, String warehouse){
        JSONArray param = JsonUtil.readJSONArray("wms/saveSignRecords");
        param.getJSONObject(0).replace("expressNo", purchaseNo);
        param.getJSONObject(0).replace("purchaseNo", purchaseNo);
        param.getJSONObject(0).replace("warehouse", warehouse);

        String result = new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API3.getApi(), param);
        return result;
    }

    /**
     * WMS: 检品查询
     */
    public String queryPurchaseInfo(WMSLoginDTO wmsLoginDTO, String purchaseNo){
        HashMap<String, String> param = new HashMap<>();
        param.put("expressNo", purchaseNo);

        String result = new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doGet(WmsAPI.WMS_API4.getApi(), param);
        return result;
    }

    /**
     * WMS: 检品查询新
     * @param wmsLoginDTO
     * @param expressNo
     * @return
     */
    public String queryWithInboundCode(WMSLoginDTO wmsLoginDTO, String expressNo){
        HashMap<String, String> param = new HashMap<>();
        param.put("expressNo", expressNo);
        return new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doGet(WmsAPI.WMS_API4_V1.getApi(), param);
    }




    /**
     * WMS: 入库确认提交
     */
    public String doStockIn(WMSLoginDTO wmsLoginDTO, String purchaseNo,String inboundCode, String orderCode, String productSku, Integer amount){
        JSONObject param = JsonUtil.readJson("wms/doStockIn");
        param.replace("amount", amount);
        param.replace("purchaseNo", purchaseNo);
        param.replace("orderCode", orderCode);
        param.replace("productSku", productSku);
        param.replace("expressNo", purchaseNo);

        if (inboundCode.contains("RK")) {
            param.put("inboundCode", inboundCode);
        }

        String result = new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API5_v1.getApi(), param);
        return result;
    }

    /**
     * WMS: 入库移库批次查询
     */
    public String queryPkg4Transfer(WMSLoginDTO wmsLoginDTO,String pkgCode){
        HashMap<String, String> param = new HashMap<>();
        param.put("pkgCode", pkgCode);

        String result = new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doGet(WmsAPI.WMS_API6.getApi(), param);
        return result;
    }

    /**
     *  WMS: 获取仓库库区
     * @param wmsLoginDTO
     * @param bindStatus
     * @return
     */
    public JSONObject regionList(WMSLoginDTO wmsLoginDTO, Integer bindStatus){
        String result = new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doGetURL(WmsAPI.WMS_API10.getApi());
        JSONObject object = JSON.parseObject(result);
        JSONArray data = object.getJSONArray("data");

        JSONObject object1 = new JSONObject();

        for (int i = 0; i < data.size(); i++) {
            JSONObject jsonObject = data.getJSONObject(i);
            String regionCode = jsonObject.getString("regionCode");
            String regionName = jsonObject.getString("regionName");
            Integer bindStatus1 = jsonObject.getInteger("bindStatus");
            if (bindStatus1 == bindStatus){
                object1.put("regionCode", regionCode);
                object1.put("regionName", regionName);
                object1.put("bindStatus", bindStatus);
                break;
            }
        }
        return object1;
    }

    /**
     * WMS: 移库提交
     */
    public String doTransfer(WMSLoginDTO wmsLoginDTO, String data, String targetRegion, String targetName){
        JSONArray param = JsonUtil.readJSONArray("wms/doTransfer");
        JSONObject paramData = param.getJSONObject(0);
        JSONObject object = JSON.parseObject(data);
        // 获取库区数据
        String regionData = getRegionData(targetRegion, targetName);
        JSONObject object1 = JSON.parseObject(regionData);

        paramData.putAll(object);
        paramData.putAll(object1);

        String result = new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API7.getApi(), param);
        return result;
    }

    /**
     * WMS: 组装移库库区数据
     * @param targetRegion
     * @param targetName
     * @return
     */
    private String getRegionData(String targetRegion, String targetName){
        JSONObject object = JsonUtil.readJson("wms/getRegionData");
        object.replace("targetRegion", targetRegion);
        object.replace("targetName", targetName);

        return object.toJSONString();
    }

    /**
     * WMS: 移库确认批次查询
     */
    public String getTransfer(WMSLoginDTO wmsLoginDTO, String pkgCode){
        HashMap<String, String> param = new HashMap<>();
        param.put("pkgCode", pkgCode);

        String result = new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doGet(WmsAPI.WMS_API8.getApi(), param);
        return result;
    }

    /**
     * WMS: 移库确认提交完成
     */
    public String doConfirm(WMSLoginDTO wmsLoginDTO, String data){
        JSONObject param = JsonUtil.strToJSONObject(data);
        param.replace("transferStatus", 1);
        String result = new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API9.getApi(), param);
        return result;
    }

    /**
     * PDA: 执行上架操作
     * @param wmsLoginDTO
     * @param pkgCode
     * @return
     */
    public String shelve(WMSLoginDTO wmsLoginDTO, String pkgCode){
        String gridCode = "A1-01-01";
        JSONObject param = new JSONObject();
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add(pkgCode);

        param.put("gridCode", gridCode);
        param.put("pkgCodeList", arrayList);

        String result = new HttpClientUtil(Headers.setWmsHeader(wmsLoginDTO)).doPostJson(WmsAPI.WMS_API12.getApi(), param);
        return result;
    }

    /**
     * WMS: 入库流程
     * @param wmsLoginDTO
     * @param expressNo
     * @param wareHouse
     */
    public void storageProcess(WMSLoginDTO wmsLoginDTO, String expressNo, String wareHouse){
        String wareCode = wmsLoginDTO.getWareHouse();

        if (!wareCode.equals(wareHouse)){
            switchHouse(wmsLoginDTO, wareHouse);
        }
        queryByExpressNo(wmsLoginDTO, expressNo);
        LogUtil.warn("【wms入库】入库签收扫条码：" + expressNo);

        saveSignRecords(wmsLoginDTO, expressNo, wareHouse);
        LogUtil.warn("【wms入库】入库签收确认！！！");

        String queryPurchaseInfo = queryWithInboundCode(wmsLoginDTO, expressNo);
        LogUtil.warn("【wms入库】入库检品查询，物流单号：" + expressNo);


        String inboundCode = JsonUtil.extractString(queryPurchaseInfo, "data.inboundCode");
        Integer inboundStatus = JsonUtil.extractInteger(queryPurchaseInfo, "data.inboundStatus");
        LogUtil.warn("【wms入库】入库单查询，入库单号：" + inboundCode + "入库单状态：" + inboundStatus);
        if(inboundStatus>2){
            return;
        }

        JSONArray jsonArray = JsonUtil.extractJSONArray(queryPurchaseInfo, "data.productDTOList");
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            String purchaseNo1 = jsonObject.getString("purchaseNo");
            String productSku = jsonObject.getString("productSku");
            Integer num = jsonObject.getInteger("num");
            String orderNo = jsonObject.getJSONArray("relationRespDTOList").getJSONObject(0).getString("orderNo");

            String doStockIn = doStockIn(wmsLoginDTO, purchaseNo1, inboundCode, orderNo, productSku, num);
            LogUtil.warn("【wms入库】简单检品入库完成！！！");

            JSONObject object = JSON.parseObject(doStockIn);
            JSONArray data = object.getJSONArray("data");
            for (int j = 0; j < data.size(); j++) {
                JSONObject jsonObject1 = data.getJSONObject(j);
                String pkgCode = jsonObject1.getString("pkgCode");

                String queryPkg4Transfer = queryPkg4Transfer(wmsLoginDTO, pkgCode);
                LogUtil.warn("【wms入库】移库查询批次，批次号：" + pkgCode);

                JSONObject object1 = JSON.parseObject(queryPkg4Transfer);
                JSONObject data1 = object1.getJSONObject("data");
                Integer combinationProductItemFlag = data1.getInteger("combinationProductItemFlag");

                // 判断批次是否为组合商品批次: 1 组合商品， 0普通商品；组合商品只能入质检区
                if (combinationProductItemFlag != null && 1 == combinationProductItemFlag){
                    JSONObject object2 = regionList(wmsLoginDTO, WmsRegionStatus.WMS_REGION_STATUS3.getBindStatus());
                    String regionCode = object2.getString("regionCode");
                    String regionName = object2.getString("regionName");

                    doTransfer(wmsLoginDTO, data1.toJSONString(), regionCode, regionName);
                    LogUtil.warn("【wms入库】移库提交操作！！");
                } else {
                    JSONObject object2 = regionList(wmsLoginDTO, WmsRegionStatus.WMS_REGION_STATUS4.getBindStatus());
                    String regionCode = object2.getString("regionCode");
                    String regionName = object2.getString("regionName");

                    doTransfer(wmsLoginDTO, data1.toJSONString(), regionCode, regionName);
                    LogUtil.warn("【wms入库】移库提交操作！！");
                }

                String transfer = getTransfer(wmsLoginDTO, pkgCode);
                LogUtil.warn("【wms入库】移库确认，批次查询；批次号：" + pkgCode);

                JSONObject object2 = JSON.parseObject(transfer);
                JSONObject data2 = object2.getJSONObject("data");
                doConfirm(wmsLoginDTO, data2.toJSONString());
                LogUtil.warn("【wms入库】移库确认，提交完成！！！");

                shelve(wmsLoginDTO, pkgCode);
                LogUtil.warn("【PDA操作】PDA执行上架操作，批次号：" + pkgCode);
            }
        }
    }
    /**
     * WMS: 移库至成品区并上架流程（批次包）
     * @param wmsLoginDTO
     * @param pkgCode
     */
    public void doTransferAndShelve(WMSLoginDTO wmsLoginDTO, String pkgCode){
        List<JSONObject> SQL015 = DBUtil.select("WMS-根据批次包查询仓库", new ContentDTO("", pkgCode));
        String wareHouse = SQL015.get(0).getString("warehouse");
        String wareCode = wmsLoginDTO.getWareHouse();

        if (!wareCode.equals(wareHouse)){
            switchHouse(wmsLoginDTO, wareHouse);
        }

        String queryPkg4Transfer = queryPkg4Transfer(wmsLoginDTO, pkgCode);
        LogUtil.warn("【wms入库】移库查询批次，批次号：" + pkgCode);

        JSONObject object1 = JSON.parseObject(queryPkg4Transfer);
        JSONObject data1 = object1.getJSONObject("data");
        Integer combinationProductItemFlag = data1.getInteger("combinationProductItemFlag");

        //移库至质检区
        transferRegion(wmsLoginDTO, pkgCode, WmsRegionStatus.WMS_REGION_STATUS3.getBindStatus());
        LogUtil.warn("【wms入库】移库至质检区成功"+ pkgCode);

        // 判断批次是否为组合商品批次: 1 组合商品， 0普通商品；非组合商品可以移库至成品区
        if (combinationProductItemFlag == null || 0 == combinationProductItemFlag){

            //移库至成品区
            transferRegion(wmsLoginDTO, pkgCode, WmsRegionStatus.WMS_REGION_STATUS4.getBindStatus());
            LogUtil.warn("【wms入库】移库至成品区成功"+ pkgCode);
        }

        //上架
        shelve(wmsLoginDTO, pkgCode);
        LogUtil.warn("【PDA操作】PDA执行上架操作，批次号：" + pkgCode);
    }

    /**
     * WMS: 根据批次包目标状态移库
     * @param wmsLoginDTO
     * @param pkgCode
     * @param pkgStatus
     */
    public void transferRegion(WMSLoginDTO wmsLoginDTO, String pkgCode, int pkgStatus){

        String queryPkg4Transfer = queryPkg4Transfer(wmsLoginDTO, pkgCode);
        LogUtil.warn("【wms入库】移库查询批次，批次号：" + pkgCode);

        JSONObject object1 = JSON.parseObject(queryPkg4Transfer);
        JSONObject data1 = object1.getJSONObject("data");

        JSONObject object2 = regionList(wmsLoginDTO, pkgStatus);
        String regionCode = object2.getString("regionCode");
        String regionName = object2.getString("regionName");

        doTransfer(wmsLoginDTO, data1.toJSONString(), regionCode, regionName);
        LogUtil.warn("【wms入库】移库提交操作！！");

        String transfer = getTransfer(wmsLoginDTO, pkgCode);
        LogUtil.warn("【wms入库】移库确认，批次查询；批次号：" + pkgCode);

        JSONObject object3 = JSON.parseObject(transfer);
        JSONObject data3 = object3.getJSONObject("data");
        doConfirm(wmsLoginDTO, data3.toJSONString());
        LogUtil.warn("【wms入库】移库确认，提交完成！！！");

    }

    /**
     * WMS: 根据订单入库操作
     * @param wmsLoginDTO
     * @param platformOrderNo
     */
    public JSONArray storageProcess(WMSLoginDTO wmsLoginDTO, String platformOrderNo){
        JSONArray inboundData = new JSONArray();
        String purchaseOrderNo = purchaseAllotOrder.getPurchaseOrderNo(platformOrderNo);
        JSONObject object = JSON.parseObject(purchaseOrderNo);

        JSONArray purchaseNos = object.getJSONArray("purchaseNo");

        for (int i = 0; i < purchaseNos.size(); i++) {
            JSONObject inboundInfo = new JSONObject();
            String purchaseNo = purchaseNos.getString(i);
            // 查询入库单信息
            List<JSONObject> inboundList = DBUtil.select("WMS-根据采购单查询入库单信息", new ContentDTO("", purchaseNo));
            if(inboundList.isEmpty()){
                continue;
            }
            String inboundCode = inboundList.get(0).getString("inbound_code");
            Integer status = inboundList.get(0).getInteger("status");

            if(status<=1){
                //根据采购单执行入库
                storageProcessV1(wmsLoginDTO,purchaseNo);
            }

            //获取物流单号列表
            List<JSONObject> sql007 = DBUtil.select("Purchase-根据采购单查询仓库，物流", new ContentDTO("1", purchaseNo));
            List<String> logisticsList = sql007.stream()
                    .map(obj -> obj.getString("logistics_number"))
                    .collect(Collectors.toList());

            //根据入库单号获取批次包列表
            List<JSONObject> sql023 = DBUtil.select("WMS-根据入库单查询批次包列表", new ContentDTO("", inboundCode));
            List<String> pkgCodeList = sql023.stream()
                    .map(obj -> obj.getString("pkg_code"))
                    .collect(Collectors.toList());

            inboundInfo.put("inboundCode",inboundCode);
            inboundInfo.put("purchaseOrderNo",purchaseNo);
            inboundInfo.put("logisticsNumberList",new JSONArray(logisticsList));
            inboundInfo.put("pkgCodeList",new JSONArray(pkgCodeList));
            inboundData.add(inboundInfo);
        }
        return inboundData;
    }

    /**
     * WMS: 根据采购单号执行入库操作
     */
    public void storageProcessV1(WMSLoginDTO wmsLoginDTO, String purchaseNo){
        List<JSONObject> sql007 = DBUtil.select("Purchase-根据采购单查询仓库，物流", new ContentDTO("1", purchaseNo));

        String wareCode = sql007.get(0).getString("ware_code");
        String oem_ware_code = sql007.get(0).getString("oem_ware_code");
        String expressNo = sql007.get(0).getString("logistics_number");

        if (wareCode == null){
            wareCode = oem_ware_code;
        }

//        System.out.println("**********************" + wareCode + "-------------" + oem_ware_code);

        storageProcess(wmsLoginDTO, expressNo, wareCode);
    }
}
